package com.java.common.base.dao;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;

import com.java.common.constant.SystemConstant;

/**
 * 
 * @author Administrator
 *
 */
public class QueryBuilder {
	private static final String SELECT_COUNT = "SELECT COUNT(*) ";
	private static final String SELECT_DISTINCT_COUNT = "SELECT COUNT(DISTINCT *) "; 

	StringBuilder sb;

	List<Object> parameters = new ArrayList<Object>();

	public QueryBuilder(){
		sb=new StringBuilder();
	}
	public QueryBuilder(String initValue){
		sb=new StringBuilder(initValue);
	}
	public QueryBuilder(StringBuilder initValue){
		sb=initValue;
	}
	/**
	 * 清除查询语句和查询条件
	 */
	public void clear(){
		this.getParams().clear();
		this.getQuery().delete(0, this.getQuery().length());
	}
	/**
	 * 使用于查询参数都是字符串类型的参数添加（需自行完善）
	 * @param expression
	 * @param value
	 * @param clazz
	 * @return
	 */
	public QueryBuilder appendCheck(String expression, String value ,Class<?> clazz){
		Object newValue=null;
		if(clazz==null){
			newValue=value;
		}else{
			if(value!=null && value.trim().length()!=0){
				if(Date.class.equals(clazz)){
					DateFormat df=new SimpleDateFormat(SystemConstant.DATE_PATTERN);
					try {
						newValue = df.parse(value);
					} catch (ParseException e) {
						throw new RuntimeException(e);
					}
				}else if(Integer.class.equals(clazz)){
					newValue=Integer.parseInt(value);
				}
			}
		}
		return appendCheck(expression,newValue);
	}
	/**
	 * 包含null值和不同类型的相关检查（如果参数为空则不添加此条件）
	 * 如果涉及到权限限定等敏感查询请使用public QueryBuilder append(String expression, Object value)
	 * @param value
	 * @return
	 */
	public QueryBuilder appendCheck(String expression, Object value){
		if(StringUtils.isBlank(expression) || value==null){return this;}
		sb.append(" ");			
		if(value instanceof String){
			String val = ((String)value).trim();
			if(val.length()==0){return this;}
			sb.append(expression).append("?");
			//如果是 like 语句
			if(expression.toLowerCase().indexOf(" like ")!=-1 && val.indexOf("%")==-1 && val.indexOf("_")==-1){
				parameters.add("%"+val+"%");
			}else{
				parameters.add(val);
			}
		}else if(value instanceof Short){
			//if(((Short)value).shortValue()==0){return this;}
			sb.append(expression).append("?");
			parameters.add(value);
		}else if(value instanceof Integer){
			//if(((Integer)value).intValue()==0){return this;}
			sb.append(expression).append("?");
			parameters.add(value);
		}else if(value instanceof Long){
			//if(((Long)value).longValue()==0){return this;}
			sb.append(expression).append("?");
			parameters.add(value);
		}else if(value.getClass().isArray()){//数组
			Object[] values = (Object[])value;
			if(values.length!=0){
				sb.append(expression).append("(");
				for (Object val:values) {
					sb.append("?,");
					parameters.add(val);
				}
				sb.deleteCharAt(sb.length()-1).append(")");
			}else{
				//如果是in而不是not in，数组为空的时候则返回空的结果集
				if(expression.toLowerCase().indexOf(" not ")==-1 && expression.toLowerCase().indexOf(" and ")!=-1 ){
					sb.append(" and 1<>1");
				}
			}
		}else if(value instanceof Collection<?>){//集合
			Collection<?> values = (Collection<?>)value;
			if(values.size()!=0){
				sb.append(expression).append("(");
				for (Object val:values) {
					sb.append("?,");
					parameters.add(val);
				}
				sb.deleteCharAt(sb.length()-1).append(")");
			}else{
				//如果是in而不是not in，集合为空的时候则返回空的结果集
				if(expression.toLowerCase().indexOf(" not ")==-1 ){
					sb.append(" and 1<>1");
				}
			}
		}else{//其他不需要特殊判断类型比如boolean、Date
			sb.append(expression).append("?");
			parameters.add(value);
		}
		return this;
	}
	/**
	 * 如果表达式或者参数为空则添加否定词（适用于参数强制不能为空的情况）
	 * 参数需要对应占位符顺序
	 * @param value
	 * @return
	 */
	public QueryBuilder appendRequired(String expression, Object value){
		if(value==null){
			sb.append(" and 1 = 2");
		}
		return this.appendCheck(expression, value);
	}

	/**
	 * 只添加参数，由调用者自己对应表达式
	 * 参数需要对应占位符顺序
	 * @param value
	 * @return
	 */
	public QueryBuilder addParams(Object value){
		parameters.add(value);
		return this;
	}
	/**
	 * 如过参数对象不为空则添加字符串表达式
	 * @param expression
	 * @param value
	 * @return
	 */
	public QueryBuilder appendStringCheck(String expression,boolean condition){
		if(!condition)return this;
		return appendString(expression);
	}
	/**
	 * 添加表达式
	 * @param value
	 * @return
	 */
	public QueryBuilder appendString(String value){
		sb.append(" ");
		sb.append(value);
		return this;
	}
	/**
	 * 返回包含hql语句的StringBuilder
	 * @return
	 */
	public StringBuilder getQuery() {
		return sb;
	}
	/**
	 * 返回对应hql的参数集合
	 * @return
	 */
	public List<Object> getParams() {
		return this.parameters;
	}
	/**
	 * 返回from关键字后面的内容
	 * @return
	 */
	public String getFromSegment(){
		int index=getQuery().toString().toUpperCase().indexOf("FROM");
		return getQuery().substring(index).replaceFirst("fetch", "");
	}
	/**
	 * 返回count查询（查询中不要包含order by）
	 * @return
	 */
	public String getCountSQL(){
		return SELECT_COUNT+getFromSegment();		
	}
	/**
	 * 返回distinct count查询（查询中不要包含order by）
	 * @return
	 */
	public String getDistinctCountSQL(){
		return SELECT_DISTINCT_COUNT+getFromSegment();		
	}
	/**
	 * 添加排序
	 * @param orders
	 */
	public void appendOrders(List<String> orders) {
		if(orders.size()!=0){
			sb.append(" order by ");
		}
		for (int i = 0; i < orders.size(); i++) {
			sb.append(orders.get(i)).append(" ");
			if(i<orders.size()-1)
				sb.append(", ");

		}
	}
}
